When viewing WooCommerce order items, you or your clients might want to have additional information on it. What if you have multiple shipping addresses and you want to see an address under each shipping rate? What if there some Fees on your orders which should have a detailed description? In this tutorial, we are going to see how to manage order item meta in WooCommerce.
Scenarios, where you’ll want to expand the order item meta data in WooCommerce, might not be so frequent, but after finishing this tutorial, you will probably have an idea where you could use this.
I came to this idea while working on a few projects with Grow Development and Shop Plugins. If you ever need to enhance your or a clients’ WooCommerce shop, be sure to check out their services and plugins.
At the end of the tutorial, you will see how we can add a shipping note under the shipping method for the delivery. This will let the delivery know when they can deliver the items.
Before we can go and add our own meta, we need to understand how the WooCommerce order item meta is stored and displayed.
Order Item Meta
Let’s learn where the item meta is stored first. WooCommerce stores the item data inside of two tables woocommerce_order_items
and woocommerce_order_itemmeta
. The latter one is the table that will hold the order item meta data. This table of the same structure as core WordPress meta tables such as postmeta. The only difference is that we don’t have a post_id
column but a order_item_id
which connects us with the item ID inside the table woocommerce_order_items
.
The columns of the meta table are:
meta_id
– an ID that is autoincremented each time a new meta is added,order_item_id
– the ID of the item in the ordermeta_key
– the key used for storing the meta (and describing it)meta_value
– the value of the stored meta
Displaying the meta
The order item meta in the order is always displayed using the same file woocommerce/includes/admin/meta-boxes/views/html-order-item-meta.php
. Depending on the type of the item, it will be called in different files such as:
- Products (line items):
woocommerce/includes/admin/meta-boxes/views/html-order-item.php
, - Shipping:
woocommerce/includes/admin/meta-boxes/views/html-order-shipping.php
, - Fees:
woocommerce/includes/admin/meta-boxes/views/html-order-fee.php
There are also other items and their meta such as coupons and taxes. But they won’t show the meta data.
The meta data is retrieved using the method get_formatted_meta_data
. This method is defined within the class WC_Order_Item
. Each meta is formatted into an array that contains:
key
– the value of themeta_key
column,value
– the value of themeta_value
column,display_key
– used for displaying the title of the meta. By default it is the same askey
,display_value
– used for displaying the value of the meta. By default it is the same asvalue
.
We can filter the display_key
and display_value
with two filters.
Each meta array is then stored to an array with the key being the ID of the order meta data. The method get_formatted_meta_data
then returns the array with all the meta data. We can also filter that array.
Hiding the Item Meta Data
If you’re storing item meta data for internal use only, you can hide them through the filter woocommerce_hidden_order_itemmeta
. It is called in the file html-order-item-meta.php
:
And here is how we can hide the meta data:
Order Item Meta Functions
There are several functions that allow us to add our own order item meta programmatically. All of the functions can be found inside of woocommerce/includes/wc-order-item-functions.php
. You will also find functions to manage order items. But since this is a tutorial for order item meta data, we will only the item meta functions.
If you’ve ever worked with the core meta functions such as add_post_meta
, you will find that these functions are the same.
Adding Order Item Meta
function wc_add_order_item_meta( $item_id, $meta_key, $meta_value, $unique = false )
The returned value is the ID of the order item meta or 0
.
Deleting Order Item Meta
wc_delete_order_item_meta( $item_id, $meta_key, $meta_value = '', $delete_all = false )
This function will return true
or false
.
Updating Order Item Meta
wc_update_order_item_meta( $item_id, $meta_key, $meta_value, $prev_value = '' )
This function will also return true
or false
.
Getting Order Item Meta
wc_get_order_item_meta( $item_id, $key, $single = true )
This function will return the meta. The difference here is that you’ll get a single result by default. In core functions, you need to specify the $single
as true
if you want a single result.
Adding Order Item Meta on Checkout
If you’ve read everything up until now, congrats! You now have a basic knowledge on how you can manage order item meta in orders. Or at least, when the time comes, you’ll know there is a tutorial that can help you 😀
When you want to see how orders are created in WooCommerce, through checkout, you will have to look at their class WC_Checkout
. This class is located at woocommerce/includes/class-wc-checkout.php
.
So, when an order is being created, we can hook into various order items and add our own item meta. Methods that manage items and allow you to hook into each item are:
create_order_line_items
– for product itemscreate_order_fee_lines
– for fee itemscreate_order_shipping_lines
– for shipping itemscreate_order_tax_lines
– for tax itemscreate_order_coupon_lines
– for coupon items
Order Item Meta Filters
We need to understand filters inside each of those methods before you can use them to add your own custom order item meta data.
Product Items
The filter woocommerce_checkout_create_order_line_item
accepts the item WC_Order_Item_Product
, $cart_item_key
which you can use for doing checks on the Cart, all the $values
of that cart item and the $order
itself.
Fee Items
In this method, the filter woocommerce_checkout_create_order_fee_item
accepts the item WC_Order_Item_Fee
, the fee key $fee_key
, the whole $fee
object and the $order
.
Shipping Items
The filter woocommerce_checkout_create_order_shipping_item
accepts the item WC_Order_Item_Shipping
, the package key, the whole package and the order.
Do also check the other two methods mentioned above for their filters and what they pass on that you can use for other calculations 🙂
Adding a Shipping Item Meta data
We are now ready for an example. For this example, I will assume that we have a textarea field at the checkout for the shipping. It will be used as a shipping note for the delivery. You could use such field to tell the delivery that you are at home only from 12:00 to 19:00 so they don’t come too early or too late.
First, we will add the shipping item meta programmatically. We will use the filter woocommerce_checkout_create_order_shipping_item
:
We are doing a basic check on the $_POST
variable. If the note is set there and if there is any value, we will then add the meta with the method add_meta_data
. If you also look closely, we are passing by reference the variable $item
. This means that all the changes that we do inside the $item
, will be there also outside of our hooked function.
The above image is now showing our meta where the title of that meta is the actual key. What if we want this key to look more as a title and not as a key used in the database? We will use the filter woocommerce_order_item_display_meta_key
.
So, what are we doing here? We are checking for the key _note
. If the current meta has that key, we will change that to Note
. This way we can use the key _note
elsewhere in the code and know that it will always be the same. But when we show the value of it, we will change the title so it looks more user friendly.
Conclusion
This was kind of a long tutorial but I hope you’ve learned something new. Most of what we have learned here can be also used for regular order items. You can search for the mentioned functions and methods and that can help you if you need to manage order items.
By managing and adding custom order item meta we can enhance even more the experience of the store owners but also of the store customers.
Have you ever had to do something with order items in WooCommerce? Let others now by sharing in the comments below.
Become a Sponsor
Hi is there a possibility to hide only certain meta_key for example meta_key:hn140 on thank you page and customer e-mail, but displayed on single product page, while using a global function in child theme?
Hi Peter, you can display what you want on a single product page by hooking into the actions used there. And since that’s a meta data of a product, you don’t have to define anything on the thankyou page or customer e-mail to hide it. Or did you refer to the order page?
I am using oceanwp theme and after adding meta data from code I see it getting displayed in various pages, I want to use this for internal use and not show to user anywhere (product page, cart, checkout, thank you or mail). How can I hide?
Hi, I want to add item meta which is SKU number for subscription orders which is not adding automatically. I am using Woocommerce subscription plugin. Can you please help me with this.
Thank you, Igor, for this very clear and helpful post. It answered a lot of questions for which I hadn’t been able to find useful information elsewhere.
WooGuru! Unfortunately, I’m an amateur. I am looking for a way how to display the number of orders in the Woo reports for a selected period / date, where the shipment price is 0 (free shipping). Every tip will be worth its weight in gold. Best Regards.
I am trying to export the metadata with the Advanced Order Export For WooCommerce plugin, do you know if you can and how?
Hi Harry, sorry for such a late response. This year is a crazy one 🙂 I have never tried it that plugin so I would not know.
There are probably some filters and actions that can be used to hook into your own code and a way to add your own data from orders.
I am looking for a script that will display the user’s three most recent orders – can you recommend where I might find this please?
Hi Sven, sorry for such a late response. I hope you’ve found what you were looking for.
On this page you can find out how to retrieve orders in various ways.
i’m trying to show product meta on the order received page (thank you page)
can you clarify how to access product meta?
Hi Moo, it depends where you want to show. I would advise you to check the templates inside of WooCommerce templates/order/order-details.php and templates/order/order-details-item.php.
If you want to show the meta of the product under each product, you can check the function get_formatted_meta_data (https://woocommerce.github.io/code-reference/files/woocommerce-includes-class-wc-order-item.html#source-view.257).
You can use the filter: woocommerce_order_item_get_formatted_meta_data to go over the items from order, then use the same approach they use to get the $product and then get the meta from it and add it to the array that is sent through that filter.
Thank you very much for helping.
Note* i’ve read your book (WooCommerce for Developers CTO) it helped me enough when i started my journey with woocommerce, i hope you update it soon with more details and specially working with APIs.
Br,
Hi Moo, I do plan to update it with some of my recent findings such as using WooCommerce tests for testing your own WC extension and such.
Thank you for let me know about this update, you’re perfect !
Hi Igor,
It’s a really great tutorial to handle the meta information in the email – thanks for this amazing summary!
I’m also trying to format the meta information a bit. Do you know where to add the changes for do_action( ‘woocommerce_order_item_meta_start’, $item_id, $item, $order, $plain_text ); so I can avoid adding etc. to the meta information
Hi,
In our user section, we have a field called ‘Legacy Account ID’, which is the customer’s account number. We do not use woocomerces own customer account ID’s.
I think this field is set via a plugin, but I do not know which plugin.
Does anyone know the meta data / meta key for this please, so that we can add the Legacy Account ID’s to the invoices?
Thank you
Hi Charlotte, unfortunately, we can’t know how to get that as it’s not a WooCommerce core field.
That should be answered by someone who worked on that. Or maybe hire someone from codeable.io (or similar) to make that happen to you.
Hello,
The legacy account id field has been added to our functions.php field by our developer so that we can add our own customer account numbers.